home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / PCMAIN.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  21KB  |  887 lines

  1. /*    SCCS Id: @(#)pcmain.c    3.0    90/01/19
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4. /* main.c - PC, ST, and Amiga NetHack */
  5. #include "hack.h"
  6.  
  7. #ifndef NO_SIGNAL
  8. #include <signal.h>
  9. #endif
  10. #include <ctype.h>
  11. #ifdef DGK
  12. #ifndef AMIGA
  13. #include <sys\stat.h>
  14. #endif
  15. #endif
  16.  
  17. #if defined(LATTICE) || defined(MACOS)
  18. extern short *switches;
  19. #endif
  20. #ifdef MACOS
  21. extern WindowPtr    HackWindow;
  22. extern short macflags;
  23. pascal boolean FDECL(startDlogFProc, (DialogPtr, EventRecord *, short *));
  24. #define msmsg mprintf
  25. #endif
  26.  
  27. #if !defined(MACOS) && !defined(LATTICE)
  28. char orgdir[PATHLEN];
  29. #endif
  30. char SAVEF[FILENAME];
  31. #ifdef MSDOS
  32. char SAVEP[FILENAME];
  33. #endif
  34.  
  35. const char *hname = "NetHack";    /* used for syntax messages */
  36. #if !defined(AMIGA) && !defined(MACOS)
  37. char obuf[BUFSIZ];    /* BUFSIZ is defined in stdio.h */
  38. #endif
  39. int hackpid;        /* not used anymore, but kept in for save files */
  40.  
  41. #if defined(DGK)
  42. struct finfo    zfinfo = ZFINFO;
  43. int i;
  44. #endif /* DGK */
  45.  
  46. #ifdef __TURBOC__    /* tell Turbo C to make a bigger stack */
  47. extern unsigned _stklen = 0x2000;    /* 8K */
  48. extern unsigned char _osmajor;
  49. #endif
  50.  
  51. #ifdef TOS
  52. extern long compiletime;
  53. boolean run_from_desktop = TRUE;    /* should we pause before exiting?? */
  54. # ifdef __GNUC__
  55. long _stksize = 16*1024;
  56. # endif
  57. #endif
  58.  
  59. #ifdef MACOS
  60. #  ifdef AZTEC
  61. #define OMASK    O_RDONLY
  62. #  else
  63. #define OMASK    (O_RDONLY | O_BINARY )
  64. #  endif
  65. # else
  66. #define OMASK    O_RDONLY
  67. #endif
  68.  
  69. #ifdef MACOS
  70. Boolean justscores;
  71. #endif
  72.  
  73. #ifdef AMIGA_WBENCH
  74. extern int FromWBench;
  75. #endif
  76.  
  77. int FDECL(main, (int,char **));
  78.  
  79. const char *classes = "ABCEHKPRSTVW";
  80.  
  81. int
  82. main(argc,argv)
  83. int argc;
  84. char *argv[];
  85. {
  86.     extern int x_maze_max, y_maze_max;
  87.     register int fd;
  88.     register char *dir;
  89. #ifndef AMIGA
  90.     int (*funcp)();
  91. #endif
  92. #ifdef TOS
  93.     long clock;
  94. # ifdef __GNUC__
  95.     extern int _unixmode;
  96.     _unixmode = 0;
  97. # endif
  98. #endif
  99. #ifdef __TURBOC__
  100.     if (_osmajor >= 3) hname = argv[0];    /* DOS 3.0+ */
  101. #endif
  102. #ifdef TOS
  103.     if (*argv[0]) {            /* only a CLI can give us argv[0] */
  104.         hname = argv[0];
  105.         run_from_desktop = FALSE;
  106.     }
  107. #endif
  108. #ifdef MACOS
  109.     AppFile    theFile;
  110.     short    message,numFiles;
  111.     SFReply    reply;
  112.  
  113.     initterm(24,80);
  114.     ObscureCursor();
  115. # ifdef SMALLDATA
  116.     init_decl();
  117. # endif
  118.     /* user might have started up with a save file, so check */
  119.     CountAppFiles(&message,&numFiles);
  120.     if (!message && numFiles) {
  121.         message = 1;
  122.  
  123.         while(message <= numFiles) {
  124.             GetAppFiles(message,&theFile);
  125.             ClrAppFiles(message);
  126.             if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE))
  127.                 break;
  128.             message++;
  129.         }
  130.         if ((theFile.fType == SAVE_TYPE)||(theFile.fType == EXPLORE_TYPE)) {
  131.             (void)strncpy(SAVEF, (char *)&theFile.fName[1],
  132.                         (int)theFile.fName[0]);
  133.             (void)strncpy(plname, (char *)&theFile.fName[1],
  134.                         (int)theFile.fName[0]);
  135.             SetVol(0L,theFile.vRefNum);
  136.             SAVEF[(int)theFile.fName[0]] = '\0';
  137.             numFiles = 1;
  138.         } else
  139.             numFiles = 0;
  140.     }
  141. #endif
  142. #if defined(LATTICE) || defined(MACOS)
  143.     switches = (short *)malloc((NROFOBJECTS+2) * sizeof(long));
  144.     for (fd = 0; fd < (NROFOBJECTS + 2); fd++)
  145.         switches[fd] = fd;
  146. #endif
  147.  
  148.  
  149.     /*
  150.      *  Initialize screen I/O before anything is displayed.
  151.      *
  152.      *  startup() must be called before initoptions()
  153.      *    due to ordering of graphics settings
  154.      *  and before error(), due to use of termcap strings.
  155.      */
  156.     gettty();
  157. #if !defined(AMIGA) && !defined(MACOS)
  158.     setbuf(stdout,obuf);
  159. #endif
  160.     startup();
  161. #if !defined(AMIGA) && !defined(MACOS)
  162.     /* Save current directory and make sure it gets restored when
  163.      * the game is exited.
  164.      */
  165.     if (getcwd(orgdir, sizeof orgdir) == NULL)
  166.         error("NetHack: current directory path too long");
  167.     funcp = (int (*)())exit; /* Kludge to get around LINT_ARGS of signal. */
  168. # ifndef NO_SIGNAL
  169.     signal(SIGINT, (SIG_RET_TYPE) funcp);    /* restore original directory */
  170. # endif
  171. #endif /* AMIGA || MACOS */
  172.  
  173. #ifndef MACOS
  174.     if ((dir = getenv("HACKDIR")) != NULL) {
  175.         Strcpy(hackdir, dir);
  176. # ifdef CHDIR
  177.         chdirx (dir, 1);
  178. # endif
  179.     }
  180. #if defined(AMIGA) && defined(CHDIR)
  181.     /*
  182.      * If we're dealing with workbench, change the directory.  Otherwise
  183.      * we could get "Insert disk in drive 0" messages. (Must be done
  184.      * before initoptions())....
  185.      */
  186.     if(argc == 0)
  187.         chdirx(HACKDIR, 1);
  188. #endif
  189.  
  190. # if defined(DGK)
  191.     /* zero "fileinfo" array to prevent crashes on level change */
  192.     for (i = 0 ; i <= MAXLEVEL; i++) {
  193.         fileinfo[i] = zfinfo;
  194.     }
  195. # endif /* DGK */
  196.  
  197.     initoptions();
  198. #ifdef AMIGA_WBENCH
  199.     ami_wbench_init(argc,argv);
  200. #endif
  201. # if defined(TOS) && defined(TEXTCOLOR)
  202.     if (flags.IBMBIOS && flags.use_color)
  203.         set_colors();
  204. # endif
  205.     if (!hackdir[0])
  206. #if !defined(LATTICE) && !defined(AMIGA)
  207.         Strcpy(hackdir, orgdir);
  208. #else
  209.         Strcpy(hackdir, HACKDIR);
  210. #endif
  211.     if(argc > 1) {
  212.         if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
  213.         /* avoid matching "-dec" for DECgraphics; since the man page
  214.          * says -d directory, hope nobody's using -desomething_else
  215.          */
  216.         argc--;
  217.         argv++;
  218.         dir = argv[0]+2;
  219.         if(*dir == '=' || *dir == ':') dir++;
  220.         if(!*dir && argc > 1) {
  221.             argc--;
  222.             argv++;
  223.             dir = argv[0];
  224.         }
  225.         if(!*dir)
  226.             error("Flag -d must be followed by a directory name.");
  227.         Strcpy(hackdir, dir);
  228.         } else
  229.  
  230.     /*
  231.      * Now we know the directory containing 'record' and
  232.      * may do a prscore().
  233.      */
  234.         if (!strncmp(argv[1], "-s", 2)) {
  235. # ifdef CHDIR
  236.         chdirx(hackdir,0);
  237. # endif
  238.         prscore(argc, argv);
  239.         exit(0);
  240.         }
  241.     }
  242. #else
  243.     initoptions();
  244. #endif    /* MACOS /* */
  245.  
  246.     /*
  247.      * It seems you really want to play.
  248.      */
  249.     setrandom();
  250.     cls();
  251. #ifdef TOS
  252.     if ((unsigned long)time(&clock) < (unsigned long)compiletime)
  253.         error("Your clock is incorrectly set!");
  254. #endif
  255.     u.uhp = 1;    /* prevent RIP on early quits */
  256.     u.ux = FAR;    /* prevent nscr() */
  257.  
  258.     /*
  259.      * Find the creation date of this game,
  260.      * so as to avoid restoring outdated savefiles.
  261.      */
  262.     /* gethdate(hname); */
  263.  
  264.     /*
  265.      * We cannot do chdir earlier, otherwise gethdate will fail.
  266.      */
  267. #ifdef CHDIR
  268.     chdirx(hackdir,1);
  269. #endif
  270.  
  271. #ifndef MACOS
  272.     /*
  273.      * Process options.
  274.      */
  275.     while(argc > 1 && argv[1][0] == '-'){
  276.         argv++;
  277.         argc--;
  278.         switch(argv[0][1]){
  279. #if defined(WIZARD) || defined(EXPLORE_MODE)
  280. # ifndef EXPLORE_MODE
  281.         case 'X':
  282. # endif
  283.         case 'D':
  284. # ifdef WIZARD
  285.             /* Must have "name" set correctly by NETHACK.CNF,
  286.              * NETHACKOPTIONS, or -u
  287.              * before this flag to enter wizard mode. */
  288. #  ifdef KR1ED
  289.             if(!strcmp(plname, WIZARD_NAME)) {
  290. #  else
  291.             if(!strcmp(plname, WIZARD)) {
  292. #  endif
  293.                 wizard = TRUE;
  294.                 break;
  295.             }
  296.             /* otherwise fall thru to discover */
  297. # endif
  298. # ifdef EXPLORE_MODE
  299.         case 'X':
  300.             discover = TRUE;
  301. # endif
  302.             break;
  303. #endif
  304. #ifdef NEWS
  305.         case 'n':
  306.             flags.nonews = TRUE;
  307.             break;
  308. #endif
  309.         case 'u':
  310.             if(argv[0][2])
  311.               (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  312.             else if(argc > 1) {
  313.               argc--;
  314.               argv++;
  315.               (void) strncpy(plname, argv[0], sizeof(plname)-1);
  316.             } else
  317.                 Printf("Player name expected after -u\n");
  318.             break;
  319.         case 'i':
  320.             if(!strcmp(argv[0]+1, "ibm")) assign_ibm_graphics();
  321.             break;
  322.         case 'd':
  323.             if(!strcmp(argv[0]+1, "dec")) assign_dec_graphics();
  324.             break;
  325. #ifdef DGK
  326.         /* Player doesn't want to use a RAM disk
  327.          */
  328.         case 'r':
  329.             ramdisk = FALSE;
  330.             break;
  331. #endif
  332.         default:
  333.             if (index(classes, toupper(argv[0][1]))) {
  334.                 /* allow -T for Tourist, etc. */
  335.                 (void) strncpy(pl_character, argv[0]+1,
  336.                            sizeof(pl_character)-1);
  337.                 break;
  338.             } else Printf("\nUnknown switch: %s\n", argv[0]);
  339.         case '?':
  340. Printf("\nUsage: %s [-d dir] -s [-[%s]] [maxrank] [name]...", hname, classes);
  341. Printf("\n       or");
  342. Printf("\n       %s [-d dir] [-u name] [-[%s]]", hname, classes);
  343. #if defined(WIZARD) || defined(EXPLORE_MODE)
  344.             Printf(" [-[DX]]");
  345. #endif
  346. #ifdef NEWS
  347.             Printf(" [-n]");
  348. #endif
  349. #ifdef DGK
  350.             Printf(" [-r]");
  351. #endif
  352.             putchar('\n');
  353.             return 0;
  354.         }
  355.     }
  356. #ifdef AMIGA_WBENCH
  357.     ami_wbench_args();
  358. #endif
  359. #ifdef DGK
  360.     set_lock_and_bones();
  361.     copybones(FROMPERM);
  362. #endif
  363. #ifdef WIZARD
  364.     if (wizard)
  365.         Strcpy(plname, "wizard");
  366.     else
  367. #endif
  368.     if (!*plname)
  369.         askname();
  370.     plnamesuffix();        /* strip suffix from name; calls askname() */
  371.                 /* again if suffix was whole name */
  372.                 /* accepts any suffix */
  373. #ifndef DGK
  374.     Strcpy(lock,plname);
  375.     Strcat(lock,".99");
  376. #endif
  377. #endif /* MACOS */
  378.     start_screen();
  379.  
  380.     /*
  381.      * Initialisation of the boundaries of the mazes
  382.      * Both boundaries have to be even.
  383.      */
  384.  
  385.     x_maze_max = COLNO-1;
  386.     if (x_maze_max % 2)
  387.         x_maze_max--;
  388.     y_maze_max = ROWNO-1;
  389.     if (y_maze_max % 2)
  390.         y_maze_max--;
  391.  
  392.     /* initialize static monster strength array */
  393.     init_monstr();
  394. #ifdef MACOS
  395.     if (!numFiles) {
  396.         askname();
  397.         if(justscores){
  398.             prscore(1,&classes);
  399.             exit(0);
  400.         }
  401. #endif
  402. #if defined(AMIGA) || defined(MACOS)
  403. # ifdef AMIGA_WBENCH
  404.     if(!FromWBench)
  405. # endif
  406.     (void) strncat(SAVEF, plname, 31-4);
  407. #else
  408.     {
  409.         int ix = strlen(SAVEF);
  410.         (void)strncat(SAVEF, plname, 8);
  411.         regularize(SAVEF+ix);
  412.     }
  413. #endif
  414. #ifndef MACOS
  415. # ifdef AMIGA_WBENCH
  416.     if(!FromWBench)
  417. # endif
  418.     Strcat(SAVEF, ".sav");
  419. #else
  420.     } else {    /* save file start, didn't askname() */
  421.         char *stripCharSuffix;
  422.  
  423.         if (stripCharSuffix = strrchr((char *)plname, '-'))
  424.             *stripCharSuffix = '\0';
  425.     }
  426.     Strcpy(lock,plname);
  427.     Strcat(lock,".99");
  428. #endif
  429.     cls();
  430.     if (
  431. #ifdef DGK
  432. # ifdef AMIGA_WBENCH
  433.         (FromWBench?1:saveDiskPrompt(1)) &&
  434. # else
  435.         saveDiskPrompt(1) &&
  436. # endif
  437. #endif /* DGK */
  438. #ifdef AMIGA_WBENCH
  439.         ((fd=ami_wbench_getsave(OMASK)) >=0) &&
  440. #else
  441.         ((fd = open(SAVEF, OMASK)) >= 0) &&
  442. #endif
  443.        /* if not up-to-date, quietly unlink file via false condition */
  444.        (uptodate(fd) || unlink(SAVEF) == 666)) {
  445. #ifdef WIZARD
  446.         /* Since wizard is actually flags.debug, restoring might
  447.          * overwrite it.
  448.          */
  449.         boolean remember_wiz_mode = wizard;
  450. #endif
  451. #ifndef NO_SIGNAL
  452.         (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  453. #endif
  454.         pline("Restoring save file...");
  455.         (void) fflush(stdout);
  456.         if(!dorecover(fd))
  457.             goto not_recovered;
  458. #ifdef WIZARD
  459.         if(!wizard && remember_wiz_mode) wizard = TRUE;
  460. #endif
  461.         pline("Hello %s, welcome to NetHack!", plname);
  462.         /* get shopkeeper set properly if restore is in shop */
  463.         (void) inshop();
  464. #ifdef EXPLORE_MODE
  465.         if (discover)
  466.             You("are in non-scoring discovery mode.");
  467. #endif
  468. #if defined(EXPLORE_MODE) || defined(WIZARD)
  469.         if (discover || wizard) {
  470.             pline("Do you want to keep the save file? ");
  471.             if(yn() == 'n'){
  472.                 (void) unlink(SAVEF);
  473. #ifdef AMIGA_WBENCH
  474.                 ami_wbench_unlink(SAVEF);
  475. #endif
  476.             }
  477.         }
  478. #endif
  479.         flags.move = 0;
  480.     } else {
  481. not_recovered:
  482.         newgame();
  483.         /* give welcome message before pickup messages */
  484.         pline("Hello %s, welcome to NetHack!", plname);
  485. #ifdef EXPLORE_MODE
  486.         if (discover)
  487.             You("are in non-scoring discovery mode.");
  488. #endif
  489.         flags.move = 0;
  490.         set_wear();
  491.         pickup(1);
  492.         read_engr_at(u.ux,u.uy);
  493.     }
  494.     
  495. #ifdef MACOS
  496.     {
  497.         short    i;
  498.         MenuHandle    theMenu;
  499.         Rect    screen;
  500.         
  501.         theMenu = GetMHandle(appleMenu);
  502.         EnableItem(theMenu, 0);
  503.         EnableItem(theMenu, 1);
  504.         theMenu = GetMHandle(fileMenu);
  505.         EnableItem(theMenu,0);
  506.         for (i = inventMenu;i <= extendMenu; i++) {
  507.             theMenu = GetMHandle(i);
  508.             EnableItem(theMenu, 0);
  509.         }
  510.         DrawMenuBar();
  511.         macflags |= fDoUpdate;
  512.         SetPort(HackWindow);
  513.         screen = HackWindow->portRect;
  514.         ValidRect(&screen);
  515.         
  516.     }
  517. #endif
  518.             
  519.     flags.moonphase = phase_of_the_moon();
  520.     if(flags.moonphase == FULL_MOON) {
  521.         You("are lucky!  Full moon tonight.");
  522.         if(!u.uluck) change_luck(1);
  523.     } else if(flags.moonphase == NEW_MOON) {
  524.         pline("Be careful!  New moon tonight.");
  525.     }
  526.  
  527.     initrack();
  528. #ifndef NO_SIGNAL
  529.     (void) signal(SIGINT, SIG_IGN);
  530. #endif
  531. #ifdef OS2
  532.     gettty(); /* somehow ctrl-P gets turned back on during startup ... */
  533. #endif
  534.  
  535.     moveloop();
  536. #ifdef MACOS 
  537.     /* Help for Mac compilers */
  538.     free_decl();
  539. #endif
  540.     return 0;
  541. }
  542.  
  543.  
  544. /*
  545.  * plname is filled either by an option (-u Player  or  -uPlayer) or
  546.  * explicitly (by being the wizard) or by askname.
  547.  * It may still contain a suffix denoting pl_character.
  548.  */
  549. void
  550. askname() {
  551. #ifndef MACOS
  552.     register int c, ct;
  553.  
  554.     Printf("\nWho are you? ");
  555.     (void) fflush(stdout);
  556.     ct = 0;
  557.     while((c = Getchar()) != '\n') {
  558.         if(c == EOF) error("End of input\n");
  559.         /* some people get confused when their erase char is not ^H */
  560.         if(c == '\b') {
  561.             if(ct) {
  562.                 ct--;
  563. #ifdef MSDOS
  564.                 msmsg("\b \b");
  565. #endif
  566.             }
  567.             continue;
  568.         }
  569.         if(ct < sizeof(plname)-1) {
  570. #if defined(MSDOS)
  571.             msmsg("%c", c);
  572. #endif
  573.             plname[ct++] = c;
  574.         }
  575.     }
  576.     plname[ct] = 0;
  577.     if(ct == 0) askname();
  578. }
  579. #else /* MACOS */
  580. /* Macintosh startup Dialog written by Andy Swanson 10/20/89
  581.         modified for to include a few more options 12/17/89 */
  582.     DialogPtr asknameDlog;
  583.     DialogTHndl    th, centreDlgBox();
  584.     int kind;
  585.     Rect box;
  586.     Handle knob;
  587.     Boolean Done;
  588.     int chtype = 0,Hit,i;
  589.     Str255 ptemp;
  590.     char *p;
  591. #define OK 1
  592. #define NAME_TEXT 3
  593. #define RADIO_MIN 5
  594. #define RADIO_MAX 17
  595. #define CAVEPERSON 7
  596. #define CLERGY 11
  597. #define VALKYRIE 15
  598. #define ANY 17
  599. #define WIZ 18
  600. #define EXP 19
  601. #define FEM 20
  602. #define NO_NEWS_BOX 21
  603. #define SCORES 22
  604. #define setCheckBox(a,b,c) {GetDItem(a,b,&kind,&knob,&box);SetCtlValue(knob,c?1:0);}
  605. #define changeRadio(a,b,c) {setCheckBox(a,b,FALSE); setCheckBox(a,c,TRUE);}
  606. #define Disable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,255);}
  607. #define Enable(b) {GetDItem(asknameDlog,b,&kind,&knob,&box);HiliteControl(knob,0);}
  608. #define Hide(b)  {GetDItem(asknameDlog,b,&kind,&knob,&box);HideControl(knob);\
  609.             SetDItem(asknameDlog,b,kind+128,knob,&box);}
  610.     justscores = FALSE;
  611.     if(p=strrchr((char *)plname, '-')){
  612.         *p = 0;
  613.         if(('a'<= p[1]) && ('z'>= p[1]))p[1] += 'A' - 'a';
  614.         pl_character[0] = p[1];
  615.         pl_character[1] = 0;
  616.         if(chtype = (int)index(classes,p[1]))
  617.             chtype -= (int)(classes)-1;
  618.         if(p[1] == 'V')
  619.             flags.female = TRUE;
  620.     }
  621.     if(chtype != 0) chtype += 4;
  622.     else chtype = 17;
  623. #ifdef THINKC4
  624.     if(!*plname && (p = getlogin()))
  625.         (void) strncpy((char *)&plname,p,sizeof(plname)-1);
  626. #endif
  627.     th = centreDlgBox(131, FALSE);
  628.     
  629.     asknameDlog = GetNewDialog(131,0,-1);
  630.     
  631.     ReleaseResource((Handle)th);
  632.     if(*plname){
  633.         GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
  634.         strncpy((char*)ptemp,(char*)&plname,255);
  635.         CtoPstr((char*)ptemp);
  636.         SetIText(knob,ptemp);
  637.     }
  638.     GetDItem(asknameDlog,chtype,&kind,&knob,&box);
  639.     SetCtlValue(knob,1);
  640.     if(flags.female){
  641.         setCheckBox(asknameDlog,FEM,TRUE);
  642.         changeDgenders(asknameDlog,TRUE);
  643.     }
  644. #ifdef NEWS
  645.     setCheckBox(asknameDlog,NO_NEWS_BOX,flags.nonews);
  646. #else
  647.     Hide(NO_NEWS_BOX);
  648. #endif
  649. #ifdef WIZARD
  650.     wizard = FALSE;
  651. # ifdef KR1ED
  652.     if (strcmp(plname,WIZARD_NAME)) {
  653. # else
  654.     if (strcmp(plname,WIZARD)) {
  655. # endif
  656. #else
  657.     {
  658. #endif
  659.         Hide(WIZ);
  660.     }
  661. #ifdef EXPLORE_MODE
  662.     setCheckBox(asknameDlog,EXP,discover);
  663. #else
  664.         Hide(EXP);
  665. #endif
  666.     SelIText(asknameDlog, NAME_TEXT, 0, 32767);
  667.     ShowWindow(asknameDlog);
  668.     Done = FALSE;
  669.     while (!Done){
  670.         ModalDialog(startDlogFProc, &Hit);
  671.         if(Hit == OK){
  672.             Done = TRUE;
  673.             GetDItem(asknameDlog,NAME_TEXT,&kind,&knob,&box);
  674.             GetIText(knob,&ptemp);
  675.             PtoCstr((char*)ptemp);
  676.             (void) strncpy((char*)&plname,(char*)ptemp,sizeof(plname)-1);
  677.             pl_character[0]=classes[chtype-5];
  678.             pl_character[1]=0;
  679.             HideWindow(asknameDlog);
  680.         } else if((Hit >= RADIO_MIN) && (Hit <= RADIO_MAX)){
  681.             extern int lastDlgBut;
  682.             
  683.             changeRadio(asknameDlog,chtype,Hit);
  684.             lastDlgBut = chtype = Hit;
  685.             if ((chtype == VALKYRIE) && !flags.female) {
  686.                 flags.female = TRUE;
  687.                 setCheckBox(asknameDlog,FEM,flags.female);
  688.                 changeDgenders(asknameDlog,TRUE);
  689.             }
  690.         } else if(Hit == WIZ) {
  691.             wizard = !wizard;
  692.             setCheckBox(asknameDlog,WIZ,wizard);
  693.         } else if(Hit == EXP) {
  694.             discover = !discover;
  695.             setCheckBox(asknameDlog,EXP,discover);
  696.         } else if(Hit == FEM) {
  697.             flags.female = !flags.female;
  698.             setCheckBox(asknameDlog,FEM,flags.female);
  699.             if(chtype == VALKYRIE) {
  700.                 chtype = ANY;
  701.                 changeRadio(asknameDlog,VALKYRIE,ANY);
  702.             }
  703.             changeDgenders(asknameDlog,flags.female);
  704.         } else if(Hit == NO_NEWS_BOX) {
  705.             flags.nonews = !flags.nonews;
  706.             setCheckBox(asknameDlog,NO_NEWS_BOX,flags.nonews);
  707.         } else if(Hit == SCORES) {
  708.             justscores = !justscores;
  709.             setCheckBox(asknameDlog,SCORES,justscores);
  710.             if(justscores) for (i=RADIO_MIN;i<SCORES;i++) {
  711.                 Disable(i);
  712.                 }
  713.             else for (i=RADIO_MIN;i<SCORES;i++)
  714.                 Enable(i);
  715.         }
  716.     }
  717.     DisposDialog(asknameDlog);
  718. }
  719.  
  720.  
  721. #define RADIO_STRING "ABCEHKPRSTVWL"
  722. int    lastDlgBut = ANY;
  723.  
  724. /* The filterProc for handling character selection from keyboard
  725.    by h+@nada.kth.se                                             */
  726. pascal boolean
  727. startDlogFProc(theDialog, theEvent, itemHit)
  728. DialogPtr theDialog;
  729. EventRecord * theEvent;
  730. short * itemHit;
  731. {
  732.     int x, c;
  733.  
  734.     if(theEvent->what == keyDown) {
  735.         c = theEvent->message & 0xFF;
  736. #ifdef BETA /* We don't want this is no shipped version */
  737.         if(c == '#') Debugger();
  738. #endif
  739.         if(c == 10 || c == 13 || c == 3) { /* Accept */
  740.             *itemHit = OK;
  741.             return TRUE;
  742.         }
  743.         if(c == '\t' || c == ' ') { /* Select */
  744.             lastDlgBut++;
  745.             if(lastDlgBut > RADIO_MAX) lastDlgBut = RADIO_MIN;
  746.             *itemHit = lastDlgBut;
  747.             return TRUE;
  748.         }
  749.         if(theEvent->modifiers & cmdKey) {
  750.             if(c >= 'a' && c <= 'z') c &= 0x5F; /* Uppercase */
  751.             switch(c) {
  752.             case 'F' :
  753.                 *itemHit = FEM;
  754.                 return TRUE;
  755.             case 'X' :
  756.                 *itemHit = EXP;
  757.                 return TRUE;
  758.             case 'N' :
  759.                 *itemHit = NO_NEWS_BOX;
  760.                 return TRUE;
  761.             case 'J' :
  762.                 *itemHit = SCORES;
  763.                 return TRUE;
  764.             default :
  765.                 for(x=0; RADIO_STRING[x]; x++) {
  766.                     if(c == RADIO_STRING[x]) {
  767.                         *itemHit = x + RADIO_MIN;
  768.                         return TRUE;
  769.                     }
  770.                 }
  771.             }
  772.             theEvent->what = nullEvent;
  773.         }
  774.     }
  775.  
  776.     return FALSE;
  777. }
  778.  
  779.  
  780. changeDgenders(Dlog,fem)
  781. DialogPtr Dlog;
  782. Boolean fem;
  783. {    int kind;
  784.     Rect box;
  785.     Handle knob;
  786.     Str255 ptemp;
  787.     if(fem){
  788.         GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
  789.         strncpy((char*)ptemp,"Cave-Woman",255);
  790.         CtoPstr((char*)ptemp);
  791.         SetCTitle(knob,ptemp);
  792.         GetDItem(Dlog,CLERGY,&kind,&knob,&box);
  793.         strncpy((char*)ptemp,"Priestess",255);
  794.         CtoPstr((char*)ptemp);
  795.         SetCTitle(knob,ptemp);
  796.     } else {
  797.         GetDItem(Dlog,CAVEPERSON,&kind,&knob,&box);
  798.         strncpy((char*)ptemp,"Cave-Man",255);
  799.         CtoPstr((char*)ptemp);
  800.         SetCTitle(knob,ptemp);
  801.         GetDItem(Dlog,CLERGY,&kind,&knob,&box);
  802.         strncpy((char*)ptemp,"Priest",255);
  803.         CtoPstr((char*)ptemp);
  804.         SetCTitle(knob,ptemp);
  805.     }
  806. }
  807. #endif /* MACOS */
  808.  
  809.  
  810. #ifdef CHDIR
  811. void
  812. chdirx(dir, wr)
  813. char *dir;
  814. boolean wr;
  815. {
  816. #ifdef AMIGA
  817.     static char thisdir[] = "";
  818. #else
  819.     static char thisdir[] = ".";
  820. #endif
  821.     if(dir && chdir(dir) < 0) {
  822.         error("Cannot chdir to %s.", dir);
  823.     }
  824.  
  825.     /* Change the default drive as well.
  826.      */
  827. #ifndef AMIGA
  828.     chdrive(dir);
  829. #endif
  830.  
  831.     /* warn the player if we can't write the record file */
  832.     /* perhaps we should also test whether . is writable */
  833.     /* unfortunately the access systemcall is worthless */
  834.     if(wr) {
  835.         register int fd;
  836.  
  837.         if(dir == NULL)
  838.         dir = thisdir;
  839. #ifdef OS2_CODEVIEW  /* explicit path on opening for OS/2 */
  840.         {
  841.         char tmp[PATHLEN];
  842.  
  843.         Strcpy(tmp, dir);
  844.         append_slash(tmp);
  845.         Strcat(tmp, RECORD);
  846.         if((fd = open(tmp, O_RDWR)) < 0) {
  847. #else
  848.         if((fd = open(RECORD, O_RDWR)) < 0) {
  849. #endif
  850. #ifdef DGK
  851. # ifndef OS2_CODEVIEW
  852.         char tmp[PATHLEN];
  853.  
  854.         Strcpy(tmp, dir);
  855.         append_slash(tmp);
  856. # endif
  857.         /* try to create empty record */
  858.  
  859. # ifdef OS2_CODEVIEW
  860.         if((fd = open(tmp, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
  861.             msmsg("Warning: cannot write %s\n", tmp);
  862. # else
  863. # ifdef AZTEC_C
  864.         /* Aztec doesn't use the third argument */
  865.         if((fd = open(RECORD, O_CREAT|O_RDWR)) < 0) {
  866.             msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
  867. # else
  868.           if((fd = open(RECORD, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
  869.             msmsg("Warning: cannot write %s%s\n", tmp, RECORD);
  870. # endif
  871. # endif
  872.             getreturn("to continue");
  873.         } else
  874.             (void) close(fd);
  875. #else
  876.         Printf("Warning: cannot write %s/%s", dir, RECORD);
  877.         getret();
  878. #endif
  879.         } else
  880.         (void) close(fd);
  881. #ifdef OS2_CODEVIEW
  882.         }
  883. #endif
  884.     }
  885. }
  886. #endif /* CHDIR /**/
  887.